home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / comma000 / comma000.asm next >
Assembly Source File  |  1991-10-18  |  7KB  |  342 lines

  1. ;COMMA000.ASM テンキーの「000」を「,」に変換する
  2.         page 58,132
  3.         .8086
  4. comment        *
  5.         COMMA000.COM (C)1991. Boko.
  6.  
  7.     テンキー部の「000」キーを「,」(カンマ)に変更する。
  8.  
  9.     常駐してINT 90(キーボードBIOS)をフックし、
  10.     キーの読み取り時にコードをすりかえる
  11.  
  12.     1991.05.19 V1.0    初版(Nifty-Serve FTOWNS1 DL3 にアップロード)
  13.     1991.06.09      常駐サイズの縮小
  14.     1991.08.11 V1.1 フリコレ4用(^^;)にコメントを追加
  15.  
  16.         *
  17.  
  18. TAB        EQU    009H    ;タブコード
  19. CR        EQU    00DH    ;キャリッジリターンコード
  20. LF        EQU    00AH    ;ラインフィードコード
  21. EOS        EQU    '$'    ;End Of String 文字列の終端(DOS call用)
  22.  
  23. CODE        SEGMENT        ;COM形式
  24.         ASSUME    CS:CODE
  25.         ASSUME    DS:CODE
  26.         ASSUME    ES:CODE
  27.  
  28.         org    002CH
  29. ENV_SEG        DW    ?        ;環境変数のセグメント(DOSが設定する)
  30.  
  31.         org    0070H
  32.  
  33.     ;    データ部
  34.     ;    (PSP内のFCB領域をワークエリアとして利用している)
  35.  
  36. KEY_INT_VEC    label    dword        ;INT 90ベクトルの保存領域
  37. KEY_INT_OFF    DW    ?
  38. KEY_INT_SEG    DW    ?
  39.  
  40. SAVE_AX        DW    ?        ;キー待ちあり?なし?の保存領域
  41.  
  42.         org    0080h
  43. COMMAND_PARAM    DB    80h  dup(?)    ;コマンドラインからのパラメータ
  44.                     ;(1文字目はパラメータの長さ)
  45.  
  46.     ;    コード部
  47.     ;
  48.  
  49.         org    0100h
  50. START:
  51.         JMP short INITIALIZE    ;初期化ルーチンへジャンプ
  52.  
  53.     ;    常駐部
  54.     ;    ~~~~~~
  55.  
  56. ENTRY_INT90H    proc    far
  57.     ;アプリケーションソフトが
  58.     ;INT 90を実行するとまず
  59.     ;ここに制御が移る
  60.  
  61.     ;INT 90 「文字の読込」のインタフェィス
  62.     ;CALL WITH
  63.     ;  AH=09H
  64.     ;  AL=0    :キー入力待ち
  65.     ;  AL=1 :キー入力待ちなし
  66.     ;RETURNS
  67.     ;  AH=0 :正常終了
  68.     ;  DH=0FFH :入力文字なし
  69.     ;  DH!=0FFH:入力文字あり
  70.     ;  DL: 文字コード/スキャンコード
  71.     ;  BH: キーアドレス
  72.     ;  BL: シフトキー状態
  73.  
  74.         CMP    AH,009H        ; 「文字の読込」の機能?
  75.         JE    ZERO_TO_COMMA
  76.         JMP    CS:KEY_INT_VEC    ;それ以外は本当のINT 90hに制御を渡す
  77. ENTRY_INT90H    endp
  78.  
  79. ZERO_TO_COMMA    proc    far
  80.     ;この部分が実行されるときには
  81.     ;ES,DS,SSが何を指しているかは
  82.     ;不定であることに注意。データ
  83.     ;部をアクセスするためにCS:で
  84.     ;セグメントオーバーライトする
  85.     ;必要がある
  86.  
  87.         STI            ;割り込み許可
  88.         MOV    CS:SAVE_AX,AX    ;呼び出し機能をセーブしておく
  89.         
  90.     ;ここで本来のINT 90を呼ぶのだ
  91.     ;が実際にINT 90Hを実行すると
  92.     ;無限ループになるのでCALLで呼
  93.     ;び出す。次のpushf~callで
  94.     ;INT 90と同じになる。
  95.  
  96.         PUSHF
  97.         CLI
  98.         CALL    CS:KEY_INT_VEC    ;本当のINT 90h FUNC 9を呼ぶ
  99.  
  100.     ;「000」キー以外は呼び出しもとの
  101.     ;アプリケーションに戻る
  102.     ;キー待ちなしが指定されていて
  103.     ;キー入力がないときも戻る
  104.  
  105.         CMP    BH,04AH        ;「000」キーのキーアドレス?
  106.         JNE    RETURN_TO_APL
  107.  
  108.     ;「000」キーの場合は一つ目と二つ目
  109.     ;の「0」は読み捨てる
  110.  
  111.         MOV    AX,CS:SAVE_AX
  112.         PUSHF
  113.         CLI
  114.         CALL    CS:KEY_INT_VEC    ;本当のINT 90h FUNC 9をコール
  115.         CMP    BH,04AH        ;「000」キーのキーアドレス?
  116.         JNE    RETURN_TO_APL
  117.  
  118.     ;「000」キーの場合三つ目の「0」を「,」
  119.     ;に変えてもとのアプリに戻る
  120.  
  121.         MOV    AX,CS:SAVE_AX
  122.         PUSHF
  123.         CLI
  124.         CALL    CS:KEY_INT_VEC    ;本当のINT 90h FUNC 9をコール
  125.         CMP    BH,04AH        ;「000」キーのキーアドレス?
  126.         JNE    RETURN_TO_APL
  127.         MOV    DL,','        ;CAMMAにすりかえる
  128. RETURN_TO_APL:
  129.  
  130.     ;呼び出しもとのアプリケーション
  131.     ;にもどる。
  132.     ;INTからの戻りなのでふつうの
  133.     ;RET命令は使えないことに注意
  134.  
  135.         IRET
  136.  
  137. ZERO_TO_COMMA    endp
  138.  
  139.     ;    初期化部
  140.     ;    ~~~~~~~~
  141.     ;初期化部はプログラムが起動
  142.     ;したときに一度だけ実行される
  143.     ;常駐終了するときに初期化部は
  144.     ;開放される
  145.  
  146.  
  147. INITIALIZE    proc
  148.  
  149.     ;コマンドラインのパラメータを
  150.     ;チェックします。
  151.  
  152.         CLD
  153.         MOV    SI,offset COMMAND_PARAM+1
  154.  
  155. SKIP_BLANK:
  156.         LODSB
  157.         CMP    AL,' '        ;空白は無視
  158.         JE    SKIP_BLANK
  159.         CMP    AL,TAB        ;タブコードは無視
  160.         JE    SKIP_BLANK
  161.         CMP    AL,CR        ;パラメータは全く無かった
  162.         JE    NO_PARAM
  163.  
  164.     ;「S」とか「R」とかの直前の文字は
  165.     ;「/」でも「-」でもよい
  166.     ;はっきりいってなんでも良い
  167.     ;(手抜き)
  168.     ;またこれ以降の文字もまったく
  169.     ;チェックしていない。したがって
  170.     ;comma000 /s /r
  171.     ;のように書くと最初のパラメータ
  172.     ;のみが有効になる。
  173.  
  174.         LODSB
  175.         CMP    AL,'S'
  176.         JE    START_STAY    ;S Stay 常駐開始
  177.         CMP    AL,'s'
  178.         JE    START_STAY
  179.         CMP    AL,'R'        ;R Remove 常駐終了
  180.         JE    END_STAY
  181.         CMP    AL,'r'
  182.         JE    END_STAY
  183. NO_PARAM:
  184.         ;パラメターなし
  185.         CALL    STAY_CHK
  186.         JE    END_STAY
  187.     ;    JMP    START_STAY    ;次に流れ込む
  188. INITIALIZE    endp
  189.  
  190.         
  191. START_STAY    PROC
  192.  
  193.     ;    常駐開始
  194.  
  195.         CALL    STAY_CHK
  196.         PUSH    CS
  197.         POP    ES        ;ES←CS
  198.         JE    ALREADY_STAY
  199.  
  200.     ;常駐しているかどうかの判断の
  201.     ;鍵になる文字列を転送する
  202.     ;PSP内を使うのはVMAPなどの
  203.     ;メモリ利用状況表示ツールで
  204.     ;PSPを見るものが多いから
  205.  
  206.         MOV    DI,offset COMMAND_PARAM
  207.         MOV    SI,offset ID_MSG
  208.         MOV    CX,27
  209.         REPNZ    MOVSB
  210.  
  211.     ;INT 90のベクトルを取得する
  212.  
  213.         MOV    AX,03590H    ;割り込みベクトルの取得
  214.         INT    021H        ;DOSシステムコール
  215.  
  216.     ;INT 90のベルトルを保存する
  217.     ;ES:BX 割込みベクトルのアドレス
  218.  
  219.         MOV    KEY_INT_OFF,BX    
  220.         MOV    KEY_INT_SEG,ES
  221.  
  222.     ;新しい割り込みベクトルの設定
  223.     ;COMMA000の入口を設定する
  224.  
  225.         MOV    DX,offset ENTRY_INT90H
  226.         MOV    AX,02590H    ;割り込みベクトルの設定
  227.         INT    021H        ;DOSシステムコール
  228.  
  229.     ;常駐開始メッセージを出力
  230.  
  231.     ;MS-DOSのシステムコールで文字を
  232.     ;出力する場合キーのチェックが
  233.     ;行われる
  234.     ;すでにINT 90は書換え済なので
  235.     ;常駐部が呼ばれることになる
  236.     ;もしもメッセージが正常に出力
  237.     ;されない時は、常駐部が変なの
  238.     ;かもしれません。
  239.  
  240.         MOV    DX,offset STR_MSG
  241.         CALL    PUTS
  242.  
  243.         MOV    ES,ENV_SEG    ;環境変数エリアの
  244.         MOV    AH,049H        ;メモリブロックの開放
  245.         INT    021H        ;DOSシステムコール
  246.         XOR    AX,AX        ;AX←0
  247.         MOV    ENV_SEG,AX    ;cf. ◎h!FM 1990-12-p148.
  248.  
  249.     ;常駐するメモリサイズの計算は
  250.     ;パラグラフ単位なので計算が
  251.     ;ちょっとめんどう
  252.     ;PSPの分を忘れてはいけない
  253.  
  254.         MOV    DX,(INITIALIZE+15-START)/10H+10H
  255.         MOV    AX,03100H    ;常駐終了
  256.         INT    021H        ;DOSシステムコール
  257. START_STAY    endp
  258.  
  259. NO_OPERATION    proc
  260.  
  261. CANT_REMOVE:    MOV    DX,offset EN2_MSG
  262.         JMP short PUT_END
  263. ALREADY_STAY:
  264.         MOV    DX,offset ST2_MSG
  265. PUT_END:
  266.         CALL    PUTS
  267.         MOV    AX,04C00H    ;プロセスの終了(リタンコード0)
  268.         INT    021H        ;DOSシステムコール
  269. NO_OPERATION    endp
  270.  
  271.  
  272. END_STAY    proc
  273.         CALL    STAY_CHK
  274.         JNE    CANT_REMOVE
  275.         ;INT90ベクタをもとに戻す
  276.         LDS    DX,ES:KEY_INT_VEC
  277.         MOV    AX,02590H    ;割り込みベクタの設定
  278.         INT    21H        ;DOSシステムコール
  279.         ;常駐していたメモリブロック開放
  280.         MOV    AH,049H        ;メモリブロック(ES)の開放
  281.         INT    21H        ;DOSシステムコール
  282.         ;常駐終了メッセージの出力
  283.         PUSH    CS
  284.         POP    DS
  285.         MOV    DX,offset END_MSG
  286.         JMP    PUT_END
  287. END_STAY    endp
  288.  
  289.  
  290.  
  291. STAY_CHK    PROC
  292.     ;すでにCOMMA000が常駐しているかどうかのチェック
  293.     ;RETURN
  294.     ; Z :COMMA000が常駐している
  295.     ; NZ:COMMA000はみつからなかった
  296.  
  297.     ;「COMMA000」の文字列がINT 90のセグメントにあるかどうかを
  298.     ;調べている。まぁこの程度のチェックで十分でしょう。
  299.     ;本当は別のソフトがINT 90をフックしてるかもしれないのだが
  300.     ;その場合は開放することもできなくなるのでチェックはしない。
  301.  
  302.     ;このルーチンからリターンした後はESの値が変わることに注意
  303.  
  304.         MOV    AX,03590H    ;割り込みベクトルの取得(ES:BX)
  305.         INT    021H        ;DOSシステムコール
  306.  
  307.         MOV    DI,offset COMMAND_PARAM
  308.         MOV    SI,offset ID_MSG
  309.         MOV    CX,ID_LEN
  310.         REPZ    CMPSB
  311.         RET
  312. STAY_CHK    ENDP
  313.  
  314.     ;    メッセージ出力
  315.     ;    (DX:メッセージ開始アドレス)
  316.     ;MS-DOSのシステムコールによる
  317.     ;文字列な出力なので
  318.     ;Townsシステムソフトウェアで実行する場合は
  319.     ;出力は見えない
  320.  
  321. PUTS        proc
  322.         MOV    AH,09H        ;文字列の出力
  323.         INT    021H        ;DOSシステムコール
  324.         RET
  325. PUTS        endp
  326.  
  327. ID_MSG        DB 24
  328.         DB 'Comma000 (C)1991. Boko.',CR,0
  329. STR_MSG        DB 'Comma000 V1.1 for FM TOWNS & FMR Series'
  330.             DB ' (C)1991. Boko.',CR,LF
  331.         DB 'テンキーの「000」を「,」に変更します。',CR,LF
  332.         DB EOS
  333. END_MSG        DB 'テンキーの「000」はもとどおりの「000」です。',CR
  334.         DB EOS
  335. ST2_MSG        DB 'Comma000はすでに常駐しています',CR
  336.         DB EOS
  337. EN2_MSG        DB 'Comma000はありません',CR
  338.         DB EOS
  339. ID_LEN        =    STR_MSG - ID_MSG
  340. CODE        ENDS
  341.         END    START
  342.